home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / yacc / flexyacc / aflex.lha / aflex / src / miscB.a < prev    next >
Text File  |  1991-07-22  |  17KB  |  621 lines

  1. -- Copyright (c) 1990 Regents of the University of California.
  2. -- All rights reserved.
  3. --
  4. -- This software was developed by John Self of the Arcadia project
  5. -- at the University of California, Irvine.
  6. --
  7. -- Redistribution and use in source and binary forms are permitted
  8. -- provided that the above copyright notice and this paragraph are
  9. -- duplicated in all such forms and that any documentation,
  10. -- advertising materials, and other materials related to such
  11. -- distribution and use acknowledge that the software was developed
  12. -- by the University of California, Irvine.  The name of the
  13. -- University may not be used to endorse or promote products derived
  14. -- from this software without specific prior written permission.
  15. -- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  16. -- IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  17. -- WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  
  19. -- TITLE  miscellaneous aflex routines
  20. -- AUTHOR: John Self (UCI)
  21. -- DESCRIPTION
  22. -- NOTES contains functions used in various places throughout aflex.
  23. -- $Header: /dc/uc/self/arcadia/aflex/ada/src/RCS/miscB.a,v 1.22 1991/07/01 21:30:37 self Exp self $ 
  24.  
  25. with MISC_DEFS, TSTRING, TEXT_IO, MISC, MAIN_BODY; 
  26. with INT_IO, CALENDAR, EXTERNAL_FILE_MANAGER; use MISC, MISC_DEFS, TEXT_IO, 
  27.   EXTERNAL_FILE_MANAGER; 
  28.  
  29. package body MISC is 
  30.   use TSTRING; 
  31.   -- action_out - write the actions from the temporary file to lex.yy.c
  32.  
  33.   procedure ACTION_OUT is 
  34.     BUF : VSTRING; 
  35.   begin
  36.     while (not TEXT_IO.END_OF_FILE(TEMP_ACTION_FILE)) loop
  37.       TSTRING.GET_LINE(TEMP_ACTION_FILE, BUF); 
  38.       if ((TSTRING.LEN(BUF) >= 2) and then ((CHAR(BUF, 1) = '%') and (CHAR(BUF, 
  39.         2) = '%'))) then 
  40.         exit; 
  41.       else 
  42.         TSTRING.PUT_LINE(BUF); 
  43.       end if; 
  44.     end loop; 
  45.   end ACTION_OUT; 
  46.  
  47.   -- bubble - bubble sort an integer array in increasing order
  48.   --
  49.   -- description
  50.   --   sorts the first n elements of array v and replaces them in
  51.   --   increasing order.
  52.   --
  53.   -- passed
  54.   --   v - the array to be sorted
  55.   --   n - the number of elements of 'v' to be sorted
  56.  
  57.   procedure BUBBLE(V : in INT_PTR; 
  58.                    N : in INTEGER) is 
  59.     K : INTEGER; 
  60.   begin
  61.     for I in reverse 2 .. N loop
  62.       for J in 1 .. I - 1 loop
  63.         if (V(J) > V(J + 1)) then 
  64.  
  65.           -- compare
  66.           K := V(J); 
  67.  
  68.           -- exchange
  69.           V(J) := V(J + 1); 
  70.           V(J + 1) := K; 
  71.         end if; 
  72.       end loop; 
  73.     end loop; 
  74.   end BUBBLE; 
  75.  
  76.  
  77.   -- clower - replace upper-case letter to lower-case
  78.  
  79.   function CLOWER(C : in INTEGER) return INTEGER is 
  80.   begin
  81.     if (ISUPPER(CHARACTER'VAL(C))) then 
  82.       return TOLOWER(C); 
  83.     else 
  84.       return C; 
  85.     end if; 
  86.   end CLOWER; 
  87.  
  88.  
  89.   -- cshell - shell sort a character array in increasing order
  90.   --
  91.   -- description
  92.   --   does a shell sort of the first n elements of array v.
  93.   --
  94.   -- passed
  95.   --   v - array to be sorted
  96.   --   n - number of elements of v to be sorted
  97.  
  98.   procedure CSHELL(V : in out CHAR_ARRAY; 
  99.                    N : in INTEGER) is 
  100.     GAP, J, JG  : INTEGER; 
  101.     K           : CHARACTER; 
  102.     LOWER_BOUND : INTEGER := V'FIRST; 
  103.   begin
  104.     GAP := N/2; 
  105.     while GAP > 0 loop
  106.       for I in GAP .. N - 1 loop
  107.         J := I - GAP; 
  108.         while (J >= 0) loop
  109.           JG := J + GAP; 
  110.  
  111.           if (V(J + LOWER_BOUND) <= V(JG + LOWER_BOUND)) then 
  112.             exit; 
  113.           end if; 
  114.  
  115.           K := V(J + LOWER_BOUND); 
  116.           V(J + LOWER_BOUND) := V(JG + LOWER_BOUND); 
  117.           V(JG + LOWER_BOUND) := K; 
  118.           J := J - GAP; 
  119.         end loop; 
  120.       end loop; 
  121.       GAP := GAP/2; 
  122.     end loop; 
  123.   end CSHELL; 
  124.  
  125.  
  126.   -- dataend - finish up a block of data declarations
  127.  
  128.   procedure DATAEND is 
  129.   begin
  130.     if (DATAPOS > 0) then 
  131.       DATAFLUSH; 
  132.  
  133.       -- add terminator for initialization
  134.       TEXT_IO.PUT_LINE("    ) ;"); 
  135.       TEXT_IO.NEW_LINE; 
  136.  
  137.       DATALINE := 0; 
  138.     end if; 
  139.   end DATAEND; 
  140.  
  141.  
  142.   -- dataflush - flush generated data statements
  143.  
  144.   procedure DATAFLUSH(FILE : in FILE_TYPE) is 
  145.   begin
  146.     TEXT_IO.NEW_LINE(FILE); 
  147.     DATALINE := DATALINE + 1; 
  148.     if (DATALINE >= NUMDATALINES) then 
  149.  
  150.       -- put out a blank line so that the table is grouped into
  151.       -- large blocks that enable the user to find elements easily
  152.       TEXT_IO.NEW_LINE(FILE); 
  153.       DATALINE := 0; 
  154.     end if; 
  155.  
  156.     -- reset the number of characters written on the current line
  157.     DATAPOS := 0; 
  158.   end DATAFLUSH; 
  159.  
  160.   procedure DATAFLUSH is 
  161.   begin
  162.     DATAFLUSH(CURRENT_OUTPUT); 
  163.   end DATAFLUSH; 
  164.   -- aflex_gettime - return current time
  165.  
  166.   function AFLEX_GETTIME return VSTRING is 
  167.     use TSTRING, CALENDAR; 
  168.     CURRENT_TIME                                            : TIME; 
  169.     CURRENT_YEAR                                            : YEAR_NUMBER; 
  170.     CURRENT_MONTH                                           : MONTH_NUMBER; 
  171.     CURRENT_DAY                                             : DAY_NUMBER; 
  172.     CURRENT_SECONDS                                         : DAY_DURATION; 
  173.     MONTH_STRING, HOUR_STRING, MINUTE_STRING, SECOND_STRING : VSTRING; 
  174.     HOUR, MINUTE, SECOND                                    : INTEGER; 
  175.     SECONDS_PER_HOUR                                        : constant 
  176.       DAY_DURATION := 3600.0; 
  177.   begin
  178.     CURRENT_TIME := CLOCK; 
  179.     SPLIT(CURRENT_TIME, CURRENT_YEAR, CURRENT_MONTH, CURRENT_DAY, 
  180.       CURRENT_SECONDS); 
  181.     case CURRENT_MONTH is 
  182.       when 1 => 
  183.         MONTH_STRING := VSTR("Jan"); 
  184.       when 2 => 
  185.         MONTH_STRING := VSTR("Feb"); 
  186.       when 3 => 
  187.         MONTH_STRING := VSTR("Mar"); 
  188.       when 4 => 
  189.         MONTH_STRING := VSTR("Apr"); 
  190.       when 5 => 
  191.         MONTH_STRING := VSTR("May"); 
  192.       when 6 => 
  193.         MONTH_STRING := VSTR("Jun"); 
  194.       when 7 => 
  195.         MONTH_STRING := VSTR("Jul"); 
  196.       when 8 => 
  197.         MONTH_STRING := VSTR("Aug"); 
  198.       when 9 => 
  199.         MONTH_STRING := VSTR("Sep"); 
  200.       when 10 => 
  201.         MONTH_STRING := VSTR("Oct"); 
  202.       when 11 => 
  203.         MONTH_STRING := VSTR("Nov"); 
  204.       when 12 => 
  205.         MONTH_STRING := VSTR("Dec"); 
  206.     end case; 
  207.  
  208.     HOUR := INTEGER(CURRENT_SECONDS)/INTEGER(SECONDS_PER_HOUR);
  209.     MINUTE := INTEGER((CURRENT_SECONDS - (HOUR*SECONDS_PER_HOUR))/60); 
  210.     SECOND := INTEGER(CURRENT_SECONDS - HOUR*SECONDS_PER_HOUR - MINUTE*60.0); 
  211.  
  212.     if (HOUR >= 10) then 
  213.       HOUR_STRING := VSTR(INTEGER'IMAGE(HOUR)); 
  214.     else 
  215.       HOUR_STRING := VSTR("0" & INTEGER'IMAGE(HOUR)); 
  216.     end if; 
  217.  
  218.     if (MINUTE >= 10) then 
  219.       MINUTE_STRING := VSTR(INTEGER'IMAGE(MINUTE)(2 .. INTEGER'IMAGE(MINUTE)'
  220.         LENGTH)); 
  221.     else 
  222.       MINUTE_STRING := VSTR("0" & INTEGER'IMAGE(MINUTE)(2 .. INTEGER'IMAGE(
  223.         MINUTE)'LENGTH)); 
  224.     end if; 
  225.  
  226.     if (SECOND >= 10) then 
  227.       SECOND_STRING := VSTR(INTEGER'IMAGE(SECOND)(2 .. INTEGER'IMAGE(SECOND)'
  228.         LENGTH)); 
  229.     else 
  230.       SECOND_STRING := VSTR("0" & INTEGER'IMAGE(SECOND)(2 .. INTEGER'IMAGE(
  231.         SECOND)'LENGTH)); 
  232.     end if; 
  233.  
  234.     return MONTH_STRING & VSTR(INTEGER'IMAGE(CURRENT_DAY)) & HOUR_STRING & ":"
  235.       & MINUTE_STRING & ":" & SECOND_STRING & INTEGER'IMAGE(CURRENT_YEAR); 
  236.   end AFLEX_GETTIME; 
  237.  
  238.   -- aflexerror - report an error message and terminate
  239.   -- overloaded function, one for vstring, one for string.
  240.   procedure AFLEXERROR(MSG : in VSTRING) is 
  241.     use TEXT_IO; 
  242.   begin
  243.     TSTRING.PUT(STANDARD_ERROR, "aflex: " & MSG); 
  244.     TEXT_IO.NEW_LINE(STANDARD_ERROR); 
  245.     MAIN_BODY.AFLEXEND(1); 
  246.   end AFLEXERROR; 
  247.  
  248.   procedure AFLEXERROR(MSG : in STRING) is 
  249.     use TEXT_IO; 
  250.   begin
  251.     TEXT_IO.PUT(STANDARD_ERROR, "aflex: " & MSG); 
  252.     TEXT_IO.NEW_LINE(STANDARD_ERROR); 
  253.     MAIN_BODY.AFLEXEND(1); 
  254.   end AFLEXERROR; 
  255.  
  256.   -- aflexfatal - report a fatal error message and terminate
  257.   -- overloaded function, one for vstring, one for string.
  258.   procedure AFLEXFATAL(MSG : in VSTRING) is 
  259.     use TEXT_IO; 
  260.   begin
  261.     TSTRING.PUT(STANDARD_ERROR, "aflex: fatal internal error " & MSG); 
  262.     TEXT_IO.NEW_LINE(STANDARD_ERROR); 
  263.     MAIN_BODY.AFLEXEND(1); 
  264.   end AFLEXFATAL; 
  265.  
  266.   procedure AFLEXFATAL(MSG : in STRING) is 
  267.     use TEXT_IO; 
  268.   begin
  269.     TEXT_IO.PUT(STANDARD_ERROR, "aflex: fatal internal error " & MSG); 
  270.     TEXT_IO.NEW_LINE(STANDARD_ERROR); 
  271.     MAIN_BODY.AFLEXEND(1); 
  272.   end AFLEXFATAL; 
  273.  
  274.   -- basename - find the basename of a file
  275.   function BASENAME return VSTRING is 
  276.     END_CHAR_POS : INTEGER := LEN(INFILENAME);
  277.     START_CHAR_POS : INTEGER;
  278.   begin
  279.     if (END_CHAR_POS = 0) then 
  280.       -- if reading standard input give everything this name
  281.       return VSTR("aflex_yy"); 
  282.     end if; 
  283.     
  284.     -- find out where the end of the basename is    
  285.     while ((END_CHAR_POS >= 1) and then
  286.            (CHAR(INFILENAME, END_CHAR_POS) /= '.')) loop
  287.       END_CHAR_POS := END_CHAR_POS - 1; 
  288.     end loop; 
  289.  
  290.     -- find out where the beginning of the basename is    
  291.     START_CHAR_POS := END_CHAR_POS; -- start at the end of the basename
  292.     while ((START_CHAR_POS > 1) and then
  293.            (CHAR(INFILENAME, START_CHAR_POS) /= '/')) loop
  294.         START_CHAR_POS := START_CHAR_POS - 1; 
  295.     end loop; 
  296.  
  297.     if (CHAR(INFILENAME, START_CHAR_POS) = '/') then
  298.         START_CHAR_POS := START_CHAR_POS + 1;
  299.     end if;
  300.     
  301.     if (END_CHAR_POS >= 1) then 
  302.       return SLICE(INFILENAME, START_CHAR_POS,  END_CHAR_POS - 1); 
  303.     else 
  304.       return INFILENAME; 
  305.     end if; 
  306.   end BASENAME; 
  307.  
  308.   -- line_directive_out - spit out a "# line" statement
  309.  
  310.   procedure LINE_DIRECTIVE_OUT(OUTPUT_FILE_NAME : in FILE_TYPE) is 
  311.   begin
  312.     if (GEN_LINE_DIRS) then 
  313.       TEXT_IO.PUT(OUTPUT_FILE_NAME, "--# line "); 
  314.       INT_IO.PUT(OUTPUT_FILE_NAME, LINENUM, 1); 
  315.       TEXT_IO.PUT(OUTPUT_FILE_NAME, " """); 
  316.       TSTRING.PUT(OUTPUT_FILE_NAME, INFILENAME); 
  317.       TEXT_IO.PUT_LINE(OUTPUT_FILE_NAME, """"); 
  318.     end if; 
  319.   end LINE_DIRECTIVE_OUT; 
  320.  
  321.  
  322.   procedure LINE_DIRECTIVE_OUT is 
  323.   begin
  324.     if (GEN_LINE_DIRS) then 
  325.       TEXT_IO.PUT("--# line "); 
  326.       INT_IO.PUT(LINENUM, 1); 
  327.       TEXT_IO.PUT(" """); 
  328.       TSTRING.PUT(INFILENAME); 
  329.       TEXT_IO.PUT_LINE(""""); 
  330.     end if; 
  331.   end LINE_DIRECTIVE_OUT; 
  332.  
  333.   -- all_upper - returns true if a string is all upper-case
  334.   function ALL_UPPER(STR : in VSTRING) return BOOLEAN is 
  335.   begin
  336.     for I in 1 .. LEN(STR) loop
  337.       if (not ((CHAR(STR, I) >= 'A') and (CHAR(STR, I) <= 'Z'))) then 
  338.         return FALSE; 
  339.       end if; 
  340.     end loop; 
  341.     return TRUE; 
  342.   end ALL_UPPER; 
  343.  
  344.   -- all_lower - returns true if a string is all lower-case
  345.   function ALL_LOWER(STR : in VSTRING) return BOOLEAN is 
  346.   begin
  347.     for I in 1 .. LEN(STR) loop
  348.       if (not ((CHAR(STR, I) >= 'a') and (CHAR(STR, I) <= 'z'))) then 
  349.         return FALSE; 
  350.       end if; 
  351.     end loop; 
  352.     return TRUE; 
  353.   end ALL_LOWER; 
  354.  
  355.   -- mk2data - generate a data statement for a two-dimensional array
  356.   --
  357.   --  generates a data statement initializing the current 2-D array to "value"
  358.  
  359.   procedure MK2DATA(FILE  : in FILE_TYPE; 
  360.                     VALUE : in INTEGER) is 
  361.   begin
  362.  
  363.     if (DATAPOS >= NUMDATAITEMS) then 
  364.       TEXT_IO.PUT(FILE, ','); 
  365.       DATAFLUSH(FILE); 
  366.     end if; 
  367.  
  368.     if (DATAPOS = 0) then 
  369.  
  370.       -- indent
  371.       TEXT_IO.PUT(FILE, "    "); 
  372.     else 
  373.       TEXT_IO.PUT(FILE, ','); 
  374.     end if; 
  375.  
  376.     DATAPOS := DATAPOS + 1; 
  377.  
  378.     INT_IO.PUT(FILE, VALUE, 5); 
  379.   end MK2DATA; 
  380.  
  381.   procedure MK2DATA(VALUE : in INTEGER) is 
  382.   begin
  383.     MK2DATA(CURRENT_OUTPUT, VALUE); 
  384.   end MK2DATA; 
  385.  
  386.   --
  387.   --  generates a data statement initializing the current array element to
  388.   --  "value"
  389.  
  390.   procedure MKDATA(VALUE : in INTEGER) is 
  391.   begin
  392.     if (DATAPOS >= NUMDATAITEMS) then 
  393.       TEXT_IO.PUT(','); 
  394.       DATAFLUSH; 
  395.     end if; 
  396.  
  397.     if (DATAPOS = 0) then 
  398.  
  399.       -- indent
  400.       TEXT_IO.PUT("    "); 
  401.     else 
  402.       TEXT_IO.PUT(','); 
  403.     end if; 
  404.  
  405.     DATAPOS := DATAPOS + 1; 
  406.  
  407.     INT_IO.PUT(VALUE, 5); 
  408.   end MKDATA; 
  409.  
  410.  
  411.   -- myctoi - return the integer represented by a string of digits
  412.  
  413.   function MYCTOI(NUM_ARRAY : in VSTRING) return INTEGER is 
  414.     TOTAL : INTEGER := 0; 
  415.     CNT   : INTEGER := TSTRING.FIRST; 
  416.   begin
  417.     while (CNT <= TSTRING.LEN(NUM_ARRAY)) loop
  418.       TOTAL := TOTAL*10; 
  419.       TOTAL := TOTAL + CHARACTER'POS(CHAR(NUM_ARRAY, CNT)) - CHARACTER'POS('0')
  420.         ; 
  421.       CNT := CNT + 1; 
  422.     end loop; 
  423.     return TOTAL; 
  424.   end MYCTOI; 
  425.  
  426.  
  427.   -- myesc - return character corresponding to escape sequence
  428.  
  429.   function MYESC(ARR : in VSTRING) return CHARACTER is 
  430.     use TEXT_IO; 
  431.   begin
  432.     case (CHAR(ARR, TSTRING.FIRST + 1)) is 
  433.       when 'a' => 
  434.         return ASCII.BEL; 
  435.       when 'b' => 
  436.         return ASCII.BS; 
  437.       when 'f' => 
  438.         return ASCII.FF; 
  439.       when 'n' => 
  440.         return ASCII.LF; 
  441.       when 'r' => 
  442.         return ASCII.CR; 
  443.       when 't' => 
  444.         return ASCII.HT; 
  445.       when 'v' => 
  446.         return ASCII.VT; 
  447.  
  448.       when '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => 
  449.  
  450.         -- \<octal>
  451.         declare
  452.           C, ESC_CHAR : CHARACTER; 
  453.           SPTR        : INTEGER := TSTRING.FIRST + 1; 
  454.         begin
  455.           ESC_CHAR := OTOI(TSTRING.SLICE(ARR, TSTRING.FIRST + 1, TSTRING.LEN(ARR
  456.             ))); 
  457.           if (ESC_CHAR = ASCII.NUL) then 
  458.             MISC.SYNERR("escape sequence for null not allowed"); 
  459.             return ASCII.SOH; 
  460.           end if; 
  461.  
  462.           return ESC_CHAR; 
  463.         end; 
  464.       when others => 
  465.         return CHAR(ARR, TSTRING.FIRST + 1); 
  466.     end case; 
  467.   end MYESC; 
  468.  
  469.  
  470.   -- otoi - convert an octal digit string to an integer value
  471.  
  472.   function OTOI(STR : in VSTRING) return CHARACTER is 
  473.     TOTAL : INTEGER := 0; 
  474.     CNT   : INTEGER := TSTRING.FIRST; 
  475.   begin
  476.     while (CNT <= TSTRING.LEN(STR)) loop
  477.       TOTAL := TOTAL*8; 
  478.       TOTAL := TOTAL + CHARACTER'POS(CHAR(STR, CNT)) - CHARACTER'POS('0'); 
  479.       CNT := CNT + 1; 
  480.     end loop; 
  481.     return CHARACTER'VAL(TOTAL); 
  482.   end OTOI; 
  483.  
  484.  
  485.   -- readable_form - return the the human-readable form of a character
  486.   --
  487.   -- The returned string is in static storage.
  488.  
  489.   function READABLE_FORM(C : in CHARACTER) return VSTRING is 
  490.   begin
  491.     if ((CHARACTER'POS(C) >= 0 and CHARACTER'POS(C) < 32) or (C = ASCII.DEL))
  492.       then 
  493.       case C is 
  494.         when ASCII.LF => 
  495.           return (VSTR("\n")); 
  496.  
  497.         -- Newline
  498.         when ASCII.HT => 
  499.           return (VSTR("\t")); 
  500.  
  501.         -- Horizontal Tab
  502.         when ASCII.FF => 
  503.           return (VSTR("\f")); 
  504.  
  505.         -- Form Feed
  506.         when ASCII.CR => 
  507.           return (VSTR("\r")); 
  508.  
  509.         -- Carriage Return
  510.         when ASCII.BS => 
  511.           return (VSTR("\b")); 
  512.  
  513.         -- Backspace
  514.         when others => 
  515.           return VSTR("\" & INTEGER'IMAGE(CHARACTER'POS(C))); 
  516.       end case; 
  517.     elsif (C = ' ') then 
  518.       return VSTR("' '"); 
  519.     else 
  520.       return VSTR(C); 
  521.     end if; 
  522.   end READABLE_FORM; 
  523.  
  524.   -- transition_struct_out - output a yy_trans_info structure
  525.   --
  526.   -- outputs the yy_trans_info structure with the two elements, element_v and
  527.   -- element_n.  Formats the output with spaces and carriage returns.
  528.  
  529.   procedure TRANSITION_STRUCT_OUT(ELEMENT_V, ELEMENT_N : in INTEGER) is 
  530.   begin
  531.     INT_IO.PUT(ELEMENT_V, 7); 
  532.     TEXT_IO.PUT(", "); 
  533.     INT_IO.PUT(ELEMENT_N, 5); 
  534.     TEXT_IO.PUT(","); 
  535.     DATAPOS := DATAPOS + TRANS_STRUCT_PRINT_LENGTH; 
  536.  
  537.     if (DATAPOS >= 75) then 
  538.       TEXT_IO.NEW_LINE; 
  539.  
  540.       DATALINE := DATALINE + 1; 
  541.       if (DATALINE mod 10 = 0) then 
  542.         TEXT_IO.NEW_LINE; 
  543.       end if; 
  544.  
  545.       DATAPOS := 0; 
  546.     end if; 
  547.   end TRANSITION_STRUCT_OUT; 
  548.  
  549.   function SET_YY_TRAILING_HEAD_MASK(SRC : in INTEGER) return INTEGER is 
  550.   begin
  551.     if (CHECK_YY_TRAILING_HEAD_MASK(SRC) = 0) then 
  552.       return SRC + YY_TRAILING_HEAD_MASK; 
  553.     else 
  554.       return SRC; 
  555.     end if; 
  556.   end SET_YY_TRAILING_HEAD_MASK; 
  557.  
  558.   function CHECK_YY_TRAILING_HEAD_MASK(SRC : in INTEGER) return INTEGER is 
  559.   begin
  560.     if (SRC >= YY_TRAILING_HEAD_MASK) then 
  561.       return YY_TRAILING_HEAD_MASK; 
  562.     else 
  563.       return 0; 
  564.     end if; 
  565.   end CHECK_YY_TRAILING_HEAD_MASK; 
  566.  
  567.   function SET_YY_TRAILING_MASK(SRC : in INTEGER) return INTEGER is 
  568.   begin
  569.     if (CHECK_YY_TRAILING_MASK(SRC) = 0) then 
  570.       return SRC + YY_TRAILING_MASK; 
  571.     else 
  572.       return SRC; 
  573.     end if; 
  574.   end SET_YY_TRAILING_MASK; 
  575.  
  576.   function CHECK_YY_TRAILING_MASK(SRC : in INTEGER) return INTEGER is 
  577.   begin
  578.  
  579. -- this test is whether both bits are on, or whether onlyy TRAIL_MASK is set
  580.     if ((SRC >= YY_TRAILING_HEAD_MASK + YY_TRAILING_MASK) or ((
  581.       CHECK_YY_TRAILING_HEAD_MASK(SRC) = 0) and (SRC >= YY_TRAILING_MASK)))
  582.       then 
  583.       return YY_TRAILING_MASK; 
  584.     else 
  585.       return 0; 
  586.     end if; 
  587.   end CHECK_YY_TRAILING_MASK; 
  588.  
  589.   function ISLOWER(C : in CHARACTER) return BOOLEAN is 
  590.   begin
  591.     return (C in 'a' .. 'z'); 
  592.   end ISLOWER; 
  593.  
  594.  
  595.   function ISUPPER(C : in CHARACTER) return BOOLEAN is 
  596.   begin
  597.     return (C in 'A' .. 'Z'); 
  598.   end ISUPPER; 
  599.  
  600.   function ISDIGIT(C : in CHARACTER) return BOOLEAN is 
  601.   begin
  602.     return (C in '0' .. '9'); 
  603.   end ISDIGIT; 
  604.  
  605.   function TOLOWER(C : in INTEGER) return INTEGER is 
  606.   begin
  607.     return C - CHARACTER'POS('A') + CHARACTER'POS('a'); 
  608.   end TOLOWER; 
  609.  
  610.   procedure SYNERR(STR : in STRING) is 
  611.     use TEXT_IO; 
  612.   begin
  613.     SYNTAXERROR := TRUE; 
  614.     TEXT_IO.PUT(STANDARD_ERROR, "Syntax error at line "); 
  615.     INT_IO.PUT(STANDARD_ERROR, LINENUM); 
  616.     TEXT_IO.PUT(STANDARD_ERROR, STR); 
  617.     TEXT_IO.NEW_LINE(STANDARD_ERROR); 
  618.   end SYNERR; 
  619.  
  620. end MISC; 
  621.